from odoo import fields, models, api
from odoo.exceptions import UserError

ADJUST_RULE = [('change', '改价'), ('fixed_up', '固定上浮'), ('rate_up', '比率上浮'), ('fixed_down', '固定下浮'), ('rate_down', '比率下浮')]


class RPPriceAdjustRule(models.Model):
    _name = "rp.price.adjust.rule"
    _description = '调价规则'
    _sql_constraints = [('unique_name', 'UNIQUE(name)', '名称必须唯一')]

    name = fields.Char(string='规则名称', required=True, copy=False, index=True)

    rule = fields.Selection(string='调价规则', selection=ADJUST_RULE)

    changed_price = fields.Float(string='改后价格', default=0)
    fixed_float = fields.Float(string='固定浮动', default=0)
    rated_float = fields.Float(string='比率浮动', default=0, digits=(3, 4))

    result = fields.Char(string='改动结果', compute='_depends_fill_result', store=True)

    active = fields.Boolean(string='启用', default=True)
    remarks = fields.Text(string='备注')

    @api.onchange('rule')
    def _onchange_rule(self):
        if self.rule == 'change':
            self.update({'fixed_float': 0, 'rated_float': 0})
        elif self.rule in ['fixed_up', 'fixed_down']:
            self.update({'changed_price': 0, 'rated_float': 0})
        elif self.rule in ['rate_up', 'rate_down']:
            self.update({'changed_price': 0, 'fixed_float': 0})

    def write(self, vals):
        # 把depends触发的write排除在外
        if len(vals) > 0 and not vals.get('result'):
            model_list = self._record_referenced(self.id)
            if len(model_list) > 0:
                desc = [f'{record._description}[{record._name}]' for record in model_list]
                error_desc = '(' + ','.join(desc) + ')'
                raise UserError(f"该记录被{error_desc}引用，无法进行操作")
        return super(RPPriceAdjustRule, self).write(vals)

    def unlink(self):
        for record in self:
            model_list = self._record_referenced(record.id)
            if len(model_list) > 0:
                desc = [f'{record._description}[{record._name}]' for record in model_list]
                error_desc = '(' + ','.join(desc) + ')'
                raise UserError(f"该记录被{error_desc}引用，无法被删除")
            return super(RPPriceAdjustRule, self).unlink()

    def _record_referenced(self, record):
        """
        查看所有引用和字段，判断是否有记录引用了指定记录
        Params:
        -record:记录ID
        Return:
        -reference_list:引用的该记录的模型
        """
        model_list = self.env.registry.models
        reference_list = []
        # NOTE 遍历所有模型
        for model_name in model_list:
            model = self.env[model_name]
            many2one_fields = [field for field in model._fields.values() if field.type == 'many2one' and field.comodel_name == self._name]
            for item in many2one_fields:
                if model.search([(item.name, '=', record)]):
                    reference_list.append(model)
        return reference_list

    @api.depends('changed_price', 'fixed_float', 'rated_float')
    def _depends_fill_result(self):
        for s in self:
            symbol = ''
            if s.rule in [ADJUST_RULE[1][0], ADJUST_RULE[2][0]]:
                symbol = '+'
            elif s.rule in [ADJUST_RULE[3][0], ADJUST_RULE[4][0]]:
                symbol = '-'
            elif s.rule == 'change':
                symbol = 'to'
            changed_price = symbol + str(s.changed_price) + ' €' if s.changed_price != 0 else ''
            fixed_float = symbol + str(s.fixed_float) + ' €' if s.fixed_float != 0 else ''
            rated_float = symbol + str(s.rated_float * 100) + ' %' if s.rated_float != 0 else ''
            s.update({'result': "{}{}{}".format(changed_price, fixed_float, rated_float)})
